package com.cardgame.controller;

import com.cardgame.dao.ArchivalDao;
import com.cardgame.dao.CardDao;
import com.cardgame.dao.RoleDao;
import com.cardgame.model.card.*;
import com.cardgame.model.deck.Deck;
import com.cardgame.model.deck.DeckService;
import com.cardgame.model.role.Role;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;

import java.util.*;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/api/deck")
public class DeckController {
    private final DeckService deckService;
    private final CardDao cardDao;
    private final RoleDao roleDao;
    private final ArchivalDao archivalDao;

    private int currentDeckId = -1;
    private String currentDeckName = "";
    private Map<Integer, Integer> currentDeckCards = new HashMap<>();
    private Integer currentDeckLeaderRoleId = null;

    public DeckController(DeckService deckService, CardDao cardDao, RoleDao roleDao, ArchivalDao archivalDao) {
        this.deckService = deckService;
        this.cardDao = cardDao;
        this.roleDao = roleDao;
        this.archivalDao = archivalDao;
    }

    @GetMapping("/list")
    @ResponseBody
    public List<Map<String, Object>> getDeckList() {
        return deckService.getAllDecks().stream()
                .filter(Deck::isPlayerControlled)
            .map(deck -> {
                Map<String, Object> deckInfo = new HashMap<>();
                deckInfo.put("id", deck.getId());
                deckInfo.put("name", deck.getName());
                deckInfo.put("roleCount", deck.getRoleCount());
                deckInfo.put("cardCount", deck.getCardCount());
                return deckInfo;
            })
            .collect(Collectors.toList());
    }

    @GetMapping("/init/{id}")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> initDeck(@PathVariable Integer id) {
        System.out.println("Initializing deck with ID: " + id);
        if (id == -1 || deckService.getDeck(id) == null) {
            currentDeckId = -1;
            currentDeckName = "新卡组";
            currentDeckCards = new HashMap<>();
            currentDeckLeaderRoleId = null;
        } else {
            Deck tmpDeck = deckService.getDeck(id);
            currentDeckId = tmpDeck.getId();
            currentDeckName = tmpDeck.getName();
            currentDeckCards = new HashMap<>(tmpDeck.getCards());
            currentDeckLeaderRoleId = tmpDeck.getLeaderRoleId();
        }
        System.out.println("Deck init: " + currentDeckName);

        Map<String, Object> deckData = new HashMap<>();
        deckData.put("id", currentDeckId);
        deckData.put("name", currentDeckName);
        List<Map<String, Object>> cards = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : currentDeckCards.entrySet())  {
            Card card = cardDao.getCardById(entry.getKey());
            Map<String, Object> cardInfo = convertCardToMap(card);
            cardInfo.put("count", entry.getValue());
            cards.add(cardInfo);
        }
        deckData.put("cards", cards);
        if (currentDeckLeaderRoleId != null) {
            Role leaderRole = roleDao.getRoleById(currentDeckLeaderRoleId);
            deckData.put("leaderRole", convertRoleToMap(leaderRole));
        }
        return ResponseEntity.ok(deckData);
    }

    @GetMapping("/{id}")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> getDeck(@PathVariable Integer id) {
        System.out.println("Fetching deck with ID: " + id);

        Map<String, Object> deckData = new HashMap<>();
        deckData.put("id", currentDeckId);
        deckData.put("name", currentDeckName);
        List<Map<String, Object>> cards = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : currentDeckCards.entrySet())  {
            Card card = cardDao.getCardById(entry.getKey());
            Map<String, Object> cardInfo = convertCardToMap(card);
            cardInfo.put("count", entry.getValue());
            cards.add(cardInfo);
        }
        deckData.put("cards", cards);
        if (currentDeckLeaderRoleId != null) {
            Role leaderRole = roleDao.getRoleById(currentDeckLeaderRoleId);
            deckData.put("leaderRole", convertRoleToMap(leaderRole));
        }
        return ResponseEntity.ok(deckData);
    }

    @GetMapping("/candidate-roles/{id}")
    @ResponseBody
    public List<Map<String, Object>> getCandidateRoles(@PathVariable Integer id) {
        // 获取所有拥有的角色
        List<Role> ownedRoles = deckService.getOwnedRoles();
        // 过滤出未加入卡组的角色
        ownedRoles = ownedRoles.stream()
                .filter(role_O -> currentDeckLeaderRoleId == null || currentDeckLeaderRoleId != role_O.getId())
                .toList();

        // 转换为前端需要的格式
        return ownedRoles.stream()
              .map(this::convertRoleToMap).collect(Collectors.toList());
    }

    @GetMapping("/candidate-cards/{id}")
    @ResponseBody
    public List<Map<String, Object>> getAvailableCards(@PathVariable Integer id) {
        // 获取所有拥有的卡牌
//        List<Card> ownedCards = new ArrayList<>(deckService.getOwnedCards());
        List<Map<String, Object>> response = new ArrayList<>();
        Map<Integer, Integer> ownedCardCounts = new HashMap<>(archivalDao.getArchival().getCards());
        // 过滤出未加入卡组的卡牌
        Map<Integer, Integer> deckCardCounts = new HashMap<>(currentDeckCards);
        for (Map.Entry<Integer, Integer> entry : ownedCardCounts.entrySet()) {
            int cardId = entry.getKey();
            int count = entry.getValue();
            int deckCount = deckCardCounts.getOrDefault(cardId, 0);
            if (deckCount < count) {
                Card card = cardDao.getCardById(cardId);
                Map<String, Object> cardInfo = convertCardToMap(card);
                cardInfo.put("count", count - deckCount);
                response.add(cardInfo);
            }
        }
        return response;
    }

    @GetMapping("/save")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> saveDeck() {
        Map<String, Object> response = new HashMap<>();
        try {
            Deck deck = deckService.saveDeck(
                    currentDeckId == -1 ? null : currentDeckId,
                    currentDeckName,
                    currentDeckCards,
                    currentDeckLeaderRoleId,
                    true
            );
            archivalDao.saveArchival();
            response.put("success", true);
            response.put("deckId", deck.getId());
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "保存失败：" + e.getMessage());
            return ResponseEntity.ok(response);
        }
    }

    @DeleteMapping("/clear-cache")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> outDeck() {
        Map<String, Object> response = new HashMap<>();
        try {
            currentDeckId = -1;
            currentDeckName = "新卡组";
            currentDeckCards = new HashMap<>();
            currentDeckLeaderRoleId = null;
            response.put("success", true);
            return ResponseEntity.ok(response);
        }
        catch (Exception e) {
            response.put("success", false);
            response.put("message", "删除失败：" + e.getMessage());
            return ResponseEntity.ok(response);
        }
    }

    @DeleteMapping("/{id}")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> deleteDeck(@PathVariable Integer id) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            if (currentDeckId != -1){
                deckService.deleteDeck(currentDeckId);
                archivalDao.saveArchival();
            }
            currentDeckId = -1;
            currentDeckName = "新卡组";
            currentDeckCards = new HashMap<>();
            currentDeckLeaderRoleId = null;
            response.put("success", true);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "删除失败：" + e.getMessage());
            return ResponseEntity.ok(response);
        }
    }

    @GetMapping("/add-card/{deck_id}/{card_id}")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> addCard(@PathVariable Integer deck_id, @PathVariable Integer card_id) {
        Map<String, Object> response = new HashMap<>();
        try {
            Card card = cardDao.getCardById(card_id);
            if (card == null) {
                response.put("success", false);
                response.put("message", "卡牌不存在");
                return ResponseEntity.badRequest().body(response);
            }
            if (currentDeckCards.containsKey(card_id)) {
                if (deckService.getOwnedCards()
                        .stream()
                        .filter(card1 -> Objects.equals(card1.getId(), card_id)).count() <= currentDeckCards.get(card_id)) {
                    response.put("success", false);
                    response.put("message", "没有足够的卡牌");
                    return ResponseEntity.badRequest().body(response);
                }
                currentDeckCards.put(card_id, currentDeckCards.get(card_id) + 1);
            } else{
                if (deckService.getOwnedCards().stream().noneMatch(card1 -> Objects.equals(card1.getId(), card_id))) {
                    response.put("success", false);
                    response.put("message", "没有足够的卡牌");
                    return ResponseEntity.badRequest().body(response);
                }
                currentDeckCards.put(card_id, 1);
            }
        }
        catch (Exception e) {
            response.put("success", false);
            response.put("message", "添加失败：" + e.getMessage());
            return ResponseEntity.ok(response);
        }
        response.put("success", true);
        return ResponseEntity.ok(response);
    }

    @GetMapping("/remove-card/{deck_id}/{card_id}")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> removeCard(@PathVariable Integer deck_id, @PathVariable Integer card_id) {
        Map<String, Object> response = new HashMap<>();
        try {
            Card card = cardDao.getCardById(card_id);
            if (card == null) {
                response.put("success", false);
                response.put("message", "卡牌不存在");
                return ResponseEntity.badRequest().body(response);
            }
            if (currentDeckCards.containsKey(card_id)) {
                if (currentDeckCards.get(card_id) <= 1) {
                    currentDeckCards.remove(card_id);
                } else {
                    currentDeckCards.put(card_id, currentDeckCards.get(card_id) - 1);
                }
            }
        }
        catch (Exception e) {
            response.put("success", false);
            response.put("message", "删除失败：" + e.getMessage());
            return ResponseEntity.ok(response);
        }
        response.put("success", true);
        return ResponseEntity.ok(response);
    }

    @GetMapping("/add-role/{deck_id}/{role_id}")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> addRole(@PathVariable Integer deck_id, @PathVariable Integer role_id) {
        System.out.println("Adding role " + role_id + " to deck " + deck_id);
        Map<String, Object> response = new HashMap<>();
        try {
            Role role = roleDao.getRoleById(role_id);
            if (role == null) {
                System.out.println("Role not found");
                response.put("success", false);
                response.put("message", "角色不存在");
                return ResponseEntity.badRequest().body(response);
            }
            if (currentDeckLeaderRoleId == null) {
                currentDeckLeaderRoleId = role_id;
            } else {
                System.out.println("Role already added");
                response.put("success", false);
                response.put("message", "已经有角色了");
                return ResponseEntity.badRequest().body(response);
            }
        }
        catch (Exception e) {
            System.out.println("Error adding role: " + e.getMessage());
            response.put("success", false);
            response.put("message", "添加失败：" + e.getMessage());
            return ResponseEntity.ok(response);
        }
        System.out.println("Role added successfully");
        response.put("success", true);
        response.put("message", "添加成功");
        return ResponseEntity.ok(response);
    }

    @GetMapping("/remove-role/{deck_id}")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> removeRole(@PathVariable Integer deck_id) {
        Map<String, Object> response = new HashMap<>();
        try {
            if (currentDeckLeaderRoleId == null) {
                response.put("success", false);
                response.put("message", "没有角色");
                return ResponseEntity.badRequest().body(response);
            }
            currentDeckLeaderRoleId = null;
        }
        catch (Exception e) {
            response.put("success", false);
            response.put("message", "删除失败：" + e.getMessage());
            return ResponseEntity.ok(response);
        }
        response.put("success", true);
        return ResponseEntity.ok(response);
    }

    private Map<String, Object> convertRoleToMap(Role role) {
        Map<String, Object> roleMap = new HashMap<>();
        roleMap.put("id", role.getId());
        roleMap.put("name", role.getName());
        roleMap.put("introduction", role.getIntroduction());
        roleMap.put("hp", role.getHp());
        roleMap.put("mp", role.getMp());
        roleMap.put("price", role.getPrice());
        roleMap.put("imageUrl", role.getImageUrl());
        Map<String, Object> skill = getSkill(role);
        roleMap.put("skill", skill);
        return roleMap;
    }

    private static Map<String, Object> getSkill(Role role) {
        Map<String, Object> skill = new HashMap<>();
        skill.put("name", role.getSkill().getSkillName());
        skill.put("introduction", role.getSkill().getIntroduction());
        skill.put("addSelfHp", role.getSkill().getAddSelfHp());
        skill.put("addSelfMp", role.getSkill().getAddSelfMp());
        skill.put("addSelfMpMax", role.getSkill().getAddSelfMpMax());
        skill.put("addEnemyHp", role.getSkill().getAddEnemyHp());
        skill.put("addEnemyMp", role.getSkill().getAddEnemyMp());
        skill.put("cost", role.getSkill().getCost());
        return skill;
    }

    private Map<String, Object> convertCardToMap(Card card) {
        Map<String, Object> cardMap = new HashMap<>();
        cardMap.put("id", card.getId());
        cardMap.put("name", card.getName());
        cardMap.put("type", card.getType());
        cardMap.put("price", card.getPrice());
        cardMap.put("imageUrl", card.getImageUrl());
        cardMap.put("cost", card.getCost());
        // 根据卡牌类型添加不同的属性
        switch(card.getType()) {
            case "role":
                cardMap.put("hp", ((RoleCard) card).getHealth());
                cardMap.put("attack", ((RoleCard) card).getAttack());
                break;
            case "action":
                cardMap.put("addSelfHP", ((ActionCard) card).getAddSelfHP());
                cardMap.put("addSelfMP", ((ActionCard) card).getAddSelfMP());
                cardMap.put("addSelfMPMAX", ((ActionCard) card).getAddSelfMPMAX());
                cardMap.put("addEnemyHP", ((ActionCard) card).getAddEnemyHP());
                cardMap.put("addEnemyMP", ((ActionCard) card).getAddEnemyMP());
                break;
            case "total_weapon":
                cardMap.put("addHPMax", ((TotalWeaponCard) card).getAddHPMax());
                break;
            case "role_weapon":
                cardMap.put("addHPMax", ((RoleWeaponCard) card).getAddHPMax());
                cardMap.put("addAttack", ((RoleWeaponCard) card).getAddAttack());
                break;
        }
        return cardMap;
    }
} 